#include "Image.hpp"

using namespace cv;
using namespace std;

const array<int, 8> dx8 = {-1, -1, -1, 0, 0, 1, 1, 1};
const array<int, 8> dy8 = {-1, 0, 1, -1, 1, -1, 0, 1};

// 判断点是否在图像范围内
bool isPointValid(const Point &pt, const Mat &img)
{
    return pt.x >= 0 && pt.x < img.cols && pt.y >= 0 && pt.y < img.rows;
}

Mat applyPerspectiveTransform(const Mat &src)
{
    if (src.empty())
        return Mat();

    const int h = src.rows;
    const int w = src.cols;

    // 源图像——目标图像的四个对应点
    vector<Point2f> srcPoints = {
        Point2f(w * 0.2f, h * 0.95f), // 左下
        Point2f(w * 0.8f, h * 0.95f), // 右下
        Point2f(w * 0.1f, h * 0.3f),  // 左上
        Point2f(w * 0.9f, h * 0.3f)};
    // 目标图像点
    const float offset = w * 0.2f;
    vector<Point2f> dstPoints = {
        Point2f(offset, h),     // 左下
        Point2f(w - offset, h), // 右下
        Point2f(offset, 0),     // 左上
        Point2f(w - offset, 0)  // 右上
    };

    // 标记选择的点
    Mat srcWithPoints = src.clone();
    for (const auto &pt : srcPoints)
    {
        circle(srcWithPoints, pt, 5, RED, -1);
    }

    // 透视变换
    Mat view;
    warpPerspective(src, view, getPerspectiveTransform(srcPoints, dstPoints),
                    src.size(), INTER_LINEAR, BORDER_CONSTANT);

    return view;
}


pair<Point, Point> findEdgeStartPoints(const Mat &binary, int y)
{
    CV_Assert(!binary.empty() && y >= 0 && y < binary.rows);

    int leftX = -1;
    int rightX = -1;

    const int middle = binary.cols / 2;

    // 查找左侧边缘点（从中间向左扫描）
    for (int x = middle; x > 0; --x)
    {
        if (binary.at<uchar>(y, x) == 255 && binary.at<uchar>(y, x - 1) == 0)
        {
            leftX = x;
            break;
        }
    }

    // 查找右侧边缘点（从中间向右扫描）
    for (int x = middle; x < binary.cols - 1; ++x)
    {
        if (binary.at<uchar>(y, x) == 255 && binary.at<uchar>(y, x + 1) == 0)
        {
            rightX = x;
            break;
        }
    }

    Point leftPt(leftX, y);
    Point rightPt(rightX, y);

    return {leftPt, rightPt};
}

// 自适应阈值二值化
uint8_t otsuThreshold(const Mat &image)
{
    const int GrayScale = 256;
    int Image_Width = image.cols;
    int Image_Height = image.rows;
    int X, Y;
    const uint8_t *data = image.data;
    vector<int> HistGram(GrayScale, 0);
    int64_t Amount = 0;
    int64_t PixelBack = 0;
    int64_t PixelIntegralBack = 0;
    int64_t PixelIntegral = 0;
    int64_t PixelIntegralFore = 0;
    int64_t PixelFore = 0;
    double OmegaBack = 0, OmegaFore = 0, MicroBack = 0, MicroFore = 0, SigmaB = 0, Sigma = 0; // 类间方差;
    uint8_t MinValue = 0, MaxValue = 0;
    uint8_t Threshold = 0;

    for (Y = 0; Y < Image_Height; Y++)
    {
        for (X = 0; X < Image_Width; X++)
        {
            HistGram[data[Y * Image_Width + X]]++; // 统计每个灰度值的个数信息
        }
    }

    for (MinValue = 0; MinValue < 256 && HistGram[MinValue] == 0; MinValue++)
        ; // 获取最小灰度的值
    for (MaxValue = 255; MaxValue > MinValue && HistGram[MaxValue] == 0; MaxValue--)
        ; // 获取最大灰度的值

    if (MaxValue == MinValue)
    {
        return MaxValue; // 图像中只有一个颜色
    }
    if (MinValue + 1 == MaxValue)
    {
        return MinValue; // 图像中只有二个颜色
    }

    for (Y = MinValue; Y <= MaxValue; Y++)
    {
        Amount += HistGram[Y]; // 像素总数
    }

    PixelIntegral = 0;
    for (Y = MinValue; Y <= MaxValue; Y++)
    {
        PixelIntegral += HistGram[Y] * Y; // 灰度值总数
    }

    SigmaB = -1;
    for (Y = MinValue; Y < MaxValue; Y++)
    {
        PixelBack = PixelBack + HistGram[Y];                                               // 前景像素点数
        PixelFore = Amount - PixelBack;                                                    // 背景像素点数
        OmegaBack = (double)PixelBack / Amount;                                            // 前景像素百分比
        OmegaFore = (double)PixelFore / Amount;                                            // 背景像素百分比
        PixelIntegralBack += HistGram[Y] * Y;                                              // 前景灰度值
        PixelIntegralFore = PixelIntegral - PixelIntegralBack;                             // 背景灰度值
        MicroBack = (double)PixelIntegralBack / PixelBack;                                 // 前景灰度百分比
        MicroFore = (double)PixelIntegralFore / PixelFore;                                 // 背景灰度百分比
        Sigma = OmegaBack * OmegaFore * (MicroBack - MicroFore) * (MicroBack - MicroFore); // g
        if (Sigma > SigmaB)
        { // 遍历最大的类间方差 g
            SigmaB = Sigma;
            Threshold = (uint8_t)Y;
        }
    }
    return Threshold;
}

int findShortestWhiteColumn(Mat &img)
{
    // 找到最短的白列
    int shortestWhiteColumnIndex = 0;
    int minWhiteCount = img.rows; // 初始化为最大可能的白色像素数

    for (int x = 0; x < img.cols; ++x) {
        int currentColumnWhiteCount = 0;
        for (int y = 0; y < img.rows; ++y) {
            if (img.at<uchar>(y, x) == 255) {
                currentColumnWhiteCount++;
            }
        }
        if (currentColumnWhiteCount < minWhiteCount) {
            minWhiteCount = currentColumnWhiteCount;
            shortestWhiteColumnIndex = x;
        }
    }

    const int numColumnsToCheck = 6;  // 各扫6列
    double sumTotal = 0.0;
    int count = 0;

    // 向左扫描6列
    for (int i = 0; i < numColumnsToCheck; ++i) {
        int x = shortestWhiteColumnIndex - i - 1;
        if (x >= 0) {
            sumTotal += countWhitePixelsInColumn(img, x);
            count++;
        }
    }

    // 向右扫描6列
    for (int i = 0; i < numColumnsToCheck; ++i) {
        int x = shortestWhiteColumnIndex + i;
        if (x < img.cols) {
            sumTotal += countWhitePixelsInColumn(img, x);
            count++;
        }
    }

    // 包含最短白列本身
    sumTotal += minWhiteCount;
    count++;

    return count > 0 ? static_cast<int>(sumTotal / count) : 0;
}


// 主函数，找到最长的白列并返回其平均白色像素数
int findWhiteColumn(Mat &img)
{
    // 找到最长的白列
    int longestWhiteColumnIndex = 0;
    int maxWhiteCount = 0;
    for (int x = 0; x < img.cols; ++x) {
        int currentColumnWhiteCount = 0;
        for (int y = 0; y < img.rows; ++y) {
            if (img.at<uchar>(y, x) == 255) {
                currentColumnWhiteCount++;
            }
        }
        if (currentColumnWhiteCount > maxWhiteCount) {
            maxWhiteCount = currentColumnWhiteCount;
            longestWhiteColumnIndex = x;
        }
    }

    const int numColumnsToCheck = 6;  // 各扫6列
    double sumTotal = 0.0;
    int count = 0;

    // 向左扫描6列
    for (int i = 0; i < numColumnsToCheck; ++i) {
        int x = longestWhiteColumnIndex - i - 1;
        if (x >= 0) {
            sumTotal += countWhitePixelsInColumn(img, x);
            count++;
        }
    }

    // 向右扫描6列
    for (int i = 0; i < numColumnsToCheck; ++i) {
        int x = longestWhiteColumnIndex + i;
        if (x < img.cols) {
            sumTotal += countWhitePixelsInColumn(img, x);
            count++;
        }
    }

    // 包含最长白列本身
    sumTotal += maxWhiteCount;
    count++;

    return count > 0 ? static_cast<int>(sumTotal / count) : 0;
}

// 新增函数，找到最长的白列并返回其x坐标
int getLongestWhiteColumnIndex(Mat &img)
{
    // 找到最长的白列
    int longestWhiteColumnIndex = 0;
    int maxWhiteCount = 0;
    for (int x = 0; x < img.cols; ++x) {
        int currentColumnWhiteCount = 0;
        for (int y = 0; y < img.rows; ++y) {
            if (img.at<uchar>(y, x) == 255) {
                currentColumnWhiteCount++;
            }
        }
        if (currentColumnWhiteCount > maxWhiteCount) {
            maxWhiteCount = currentColumnWhiteCount;
            longestWhiteColumnIndex = x;
        }
    }

    return longestWhiteColumnIndex;
}

// 辅助函数，计算某一列中白色像素的数量
int countWhitePixelsInColumn(Mat &img, int col) {
    int whiteCount = 0;
    for (int y = 0; y < img.rows; ++y) {
        if (img.at<uchar>(y, col) == 255) {
            whiteCount++;
        }
    }
    return whiteCount;
}



int iswandao(int& sb,int& prsb){
    int error = sb - prsb;
    if (abs(error) > 30)
    {
        return 1;
    } else
        return 0;
}



// 停车保护
int isParking(Mat &img)
{
    int chujie = 0;
    if (img.at<uchar>(105, 80) == 0 && img.at<uchar>(106, 80) == 0 &&img.at<uchar>(104, 80) == 0 
    && img.at<uchar>(105, 79) == 0 && img.at<uchar>(105, 81) == 0)
    {
        chujie = 1;
    }
    else
    {
        chujie = 0;
    }
    return chujie;
}

int changerate(float& y,float& pry){
    int error = y - pry;
    int jieguo = error;
    if(jieguo = 0){
        return 0;
    }else if(jieguo > 2){
        return 1;
    }else if(jieguo < -2){
        return -1;
    }else{
        return 2;
    }
}

int zebra(Mat& img){
    int zebra_up = img.rows * 0.2;
    int zebra_down = img.rows * 0.6;
    int zebra_left = img.cols * 0.2;
    int zebra_right = img.cols * 0.6;
    
    int mid_col = img.cols / 2;
    int total_transitions = 0;
    int num_rows = zebra_down - zebra_up;
    
    for (int row = zebra_up; row < zebra_down; ++row) {
        int left_transitions = 0;
        int right_transitions = 0;
        
        for (int col = mid_col; col > zebra_left; --col) {
            if (img.at<uchar>(row, col) != img.at<uchar>(row, col - 1)) {
                ++left_transitions;
            }
        }
        
        for (int col = mid_col; col < zebra_right; ++col) {
            if (img.at<uchar>(row, col) != img.at<uchar>(row, col + 1)) {
                ++right_transitions;
            }
        }
        
        total_transitions += left_transitions + right_transitions;
    }
    
    int average_transitions = total_transitions ; // *2 because we check both left and right sides
    
    return average_transitions;
}


// int guaiddian(Mat& img){
//     int prevCenterX = -1;
//     // 用于存储历史中心点，实现滑动平均
//     std::vector<int> centerXHistory;
//     // 滑动窗口大小
//     const int WINDOW_SIZE = 5;

//     for (int y = img.rows - 1; y >= 0; --y)
//     {
//         int middleCol = img.cols / 2;
//         int startX = (prevCenterX != -1) ? prevCenterX : middleCol;

//         // 查找左侧边缘点（从startX往左）
//         int leftX = -1;
//         for (int x = startX; x > 0; --x)
//         {
//             if (img.at<uchar>(y, x) == 255 && img.at<uchar>(y, x - 1) == 0)
//             {
//                 leftX = x;
//                 break;
//             }
//         }

//         // 查找右侧边缘点（从startX往右）
//         int rightX = -1;
//         for (int x = startX; x < img.cols - 1; ++x)
//         {
//             if (img.at<uchar>(y, x) == 255 && img.at<uchar>(y, x + 1) == 0)
//             {
//                 rightX = x;
//                 break;
//             }
//         }

//         // 计算当前中心点
//         int currentCenterX = -1;
//         if (leftX != -1 && rightX != -1) {
//             currentCenterX = (leftX + rightX) / 2;
            
//             // 添加到历史记录
//             centerXHistory.push_back(currentCenterX);
//             // 保持窗口大小固定
//             if (centerXHistory.size() > WINDOW_SIZE) {
//                 centerXHistory.erase(centerXHistory.begin());
//             }
            
//             // 计算滑动平均
//             if (centerXHistory.size() >= 3) {
//                 int sum = 0;
//                 for (int val : centerXHistory) {
//                     sum += val;
//                 }
//                 currentCenterX = sum / centerXHistory.size();
//             }
            
//             prevCenterX = currentCenterX;
//         }
//     }int prevCenterX = -1;
//     // 用于存储历史中心点，实现滑动平均
//     std::vector<int> centerXHistory;
//     // 滑动窗口大小
//     const int WINDOW_SIZE = 5;

//     for (int y = img.rows - 1; y >= 0; --y)
//     {
//         int middleCol = img.cols / 2;
//         int startX = (prevCenterX != -1) ? prevCenterX : middleCol;

//         // 查找左侧边缘点（从startX往左）
//         int leftX = -1;
//         for (int x = startX; x > 0; --x)
//         {
//             if (img.at<uchar>(y, x) == 255 && img.at<uchar>(y, x - 1) == 0)
//             {
//                 leftX = x;
//                 break;
//             }
//         }

//         // 查找右侧边缘点（从startX往右）
//         int rightX = -1;
//         for (int x = startX; x < img.cols - 1; ++x)
//         {
//             if (img.at<uchar>(y, x) == 255 && img.at<uchar>(y, x + 1) == 0)
//             {
//                 rightX = x;
//                 break;
//             }
//         }

//         // 计算当前中心点
//         int currentCenterX = -1;
//         if (leftX != -1 && rightX != -1) {
//             currentCenterX = (leftX + rightX) / 2;
            
//             // 添加到历史记录
//             centerXHistory.push_back(currentCenterX);
//             // 保持窗口大小固定
//             if (centerXHistory.size() > WINDOW_SIZE) {
//                 centerXHistory.erase(centerXHistory.begin());
//             }
            
//             // 计算滑动平均
//             if (centerXHistory.size() >= 3) {
//                 int sum = 0;
//                 for (int val : centerXHistory) {
//                     sum += val;
//                 }
//                 currentCenterX = sum / centerXHistory.size();
//             }
            
//             prevCenterX = currentCenterX;
//         }
//     }
//     return prevCenterX;
// }